/**
 * @file      log4xecho.h
 * @copyright Copyright (c) 2019, ZCW Co., Ltd. All Rights Reserved.
 * @brief     brief
 * @author    caiwang213@qq.com
 * @date      2019-08-11 10:43:21
 *
 * @note
 *  log4xecho.h defines
 */
#ifndef __LOG4XECHO_H__
#define __LOG4XECHO_H__
#include "log4x.h"
#include <string>
#include <vector>
#include <map>
using namespace std;

namespace log4x
{
class ilog4x_listener;
class LOG4X_API ilog4x_echo
{
public:
    /**
     * @brief 启动日志回显监控
     *
     * @param [in] logFile 日志文件完全路径
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see stop
     */
    virtual int start(const string& logFile) = 0;

    /**
     * @brief 停止日志回显监控
     *
     * @return void.
     *
     * @see start
     */
    virtual void stop() = 0;

    /**
     * @brief 暂停打印
     *
     * @param [in] enable 是否暂停
     *                    - true  暂停
     *                    - false 继续
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see start, stop, refresh
     */
    virtual int pause(bool enable = true) = 0;

    /**
     * @brief 暂停的情况下手动刷新一次
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see pause
     */
    virtual int refresh() = 0;

    /**
     * @brief 过滤日志等级, 高亮关键字(正则表达式)
     *
     * @param [in] levels 日等级控制位
     *                    - bit0 (白)LOG_LEVEL_TRACE
     *                    - bit1 (绿)LOG_LEVEL_DEBUG
     *                    - bit2 (蓝)LOG_LEVEL_INFO
     *                    - bit3 (黄)LOG_LEVEL_WARN
     *                    - bit4 (红)LOG_LEVEL_ERROR
     *                    - bit5 (紫)LOG_LEVEL_FATAL
     *
     * @param [in] keyword 高亮关键字
     * @param [in] regex   高亮正则表达式匹配字符串(没有实现)
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see start, stop
     */
    virtual int filter(unsigned levels, const string& keyword = "", const string& regex = "") = 0;

    /**
     * @brief 设置日志回显时间间隔
     *
     * @param [in] ms 回显时间间隔, 默认500毫秒
     *
     * @return void
     *
     * @see start, stop
     */
    virtual void setInterval(int ms = 500) = 0;

    /**
     * @brief 设置日志回显监听器
     *
     * @param [in] listener 回显监听器
     *
     * @return void
     *
     * @see start, stop
     */
    virtual void setEcho(ilog4x_listener *listener) = 0;

    /**
     * @brief 根据执行文件完全路径或日志文件完全路径获取进程ID相关信息
     *
     * @param [in]  fullPath 执行文件完全路径或日志文件完全路径
     * @param [out] dir      日志文件所在文件夹全路径(包含日期)
     * @param [out] pname    进程名
     * @param [out] pids     进程ID列表
     * @param [out] keys     模块列表
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see getFileName
     */
    virtual int getInfo(const string& fullPath, string &dir, string& pname, vector<string>& pids, vector<string>& keys) = 0;

    /**
     * @brief 根据给定日志文件夹路径与进程名获取相应进程所有信息
     *
     * @param [in]  dir   日志文件所在文件夹全路径(包含日期)
     * @param [in]  pname 进程名
     * @param [out] pids  进程ID列表
     * @param [out] keys  模块列表
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see getFileName
     */
    virtual int getInfo(const string& dir, const string& pname, vector<string>& pids, vector<string>& keys) = 0;

    /**
     * @brief 根据给定日志文件夹路径获取所有进程所有信息
     *
     * @param [in]  dir    日志文件所在文件夹全路径(包含日期)
     * @param [out] pnames 进程(程序)名列表
     * @param [out] pids   每个进程(程序)对应的进程ID列表
     * @param [out] keys   每个进程(程序)对应的日志模块列表
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see getFileName
     */
    virtual int getInfo(const string& dir, vector<string>& pnames, map<string, vector<string> >& mpids, map<string, vector<string> >& mkeys) = 0;

    /**
     * @brief 根据日志文件所在文件夹路径、进程名、进程ID等获取最新完整日志文件路径
     *
     * @param [in] dir   日志文件所在文件夹全路径(包含日期)
     * @param [in] pname 进程名
     * @param [in] pids  进程ID列表
     * @param [in] key   模块名, 为空时获取到的文件为全局日志文件
     *
     * @return 成功返回0. 失败返回-1.
     *
     * @see getFileName
     */
    virtual string getFileName(const string& dir, const string& pname, const string& pid, const string& key = "") = 0;

public:
    /**
     * @brief 创建一个ilog4x_echo实例
     *
     * @return 成功返回登录句柄, 失败返回NULL.
     *
     * @see destroy
     */
    static ilog4x_echo* create();

    /**
     * @brief 销毁一个ilog4x_echo实例
     *
     * @param [in] echo @ref create 返回值
     *
     * @see create
     */
    static void destroy(ilog4x_echo *echo);
};

typedef struct
{
    int                pos;                                /**< 高亮字符串首字符位置 */
    int                len;                                /**< 高亮字符串长度 */
} log4x_hl_t;

class ilog4x_listener
{
public:
    /**
     * @brief 回显日志信息监听回调
     *
     * @param [out] line     日志信息, 每次回调一行
     * @param [out] level    当前日志行日志等级(UI要根据等级给相应的日志着不同的颜色)
     * @param [out] hlsearch 当前日志信息被高亮的字符串位置与长度信息
     *
     * @return void
     */
    virtual void echo(const string& line, int level, const vector<log4x_hl_t>& hlsearch) = 0;
};
}
#endif
